package ph.com.gs3.formalistics.model.valueobjects.business.form;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import ph.com.gs3.formalistics.global.utilities.logging.FLLogger;

public class FormField {

	public static final String TAG = FormField.class.getSimpleName();

	public static enum FieldType {
		TEXT_FIELD, TEXT_AREA, DROPDOWN, CHECK_BOX_GROUP, SELECT_MANY, RADIO_BUTTON_GROUP, DATE_PICKER, TIME_PICKER, DATE_TIME_PICKER, BARCODE_SCANNER, SINGLE_ATTACHMENT, UNSUPPORTED
	}

	private String id;
	private String label;
	private FieldType type;

	private String placeHolder;
	private String value;
	private List<String> options;
	private boolean enabled = true;

	public static FormField createFromJSON(JSONObject rawJSON) throws InvalidFormFieldException {

		FormField formField = new FormField();

		// check for missing required values
		String[] requiredKeys = { "id", "type" };
		String missingKeysString = "";
		boolean hasMissingKeys = false;

		for (String requiredKey : requiredKeys) {
			if (!rawJSON.has(requiredKey)) {
				missingKeysString += requiredKey + ", ";
				hasMissingKeys = true;
			}
		}

		if (hasMissingKeys) {
			missingKeysString = missingKeysString.substring(0, missingKeysString.length() - 2);
			String message = "The following key(s) are missing: (" + missingKeysString
			        + ") from raw JSON " + rawJSON;

			// FLLogger.e(TAG, message);
			throw new InvalidFormFieldException(message);

		}

		try {
			formField.id = rawJSON.getString("id");
			formField.label = rawJSON.getString("label");

			formField.setType(rawJSON.getString("type"));

			// optional fields
			if (rawJSON.has("value")) {
				formField.value = rawJSON.getString("value");
			}

			if (rawJSON.has("placeholder")) {
				formField.placeHolder = rawJSON.getString("placeholder");
			}

			if (rawJSON.has("options")) {
				JSONArray optionsJSON = new JSONArray(rawJSON.getString("options"));
				formField.options = new ArrayList<String>();

				for (int i = 0; i < optionsJSON.length(); i++) {
					formField.options.add(optionsJSON.getString(i));
				}
			}

		} catch (JSONException e) {
			throw new InvalidFormFieldException(rawJSON.toString(), e);
		}

		return formField;

	}

	// ========================================================================
	// Getters & Setters

	public String getId() {
		return id;
	}

	public String getLabel() {
		return label;
	}

	public FieldType getType() {
		return type;
	}

	public String getPlaceHolder() {
		return placeHolder;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public List<String> getOptions() {
		return options;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	private void setType(String type) {

		this.type = convertTypeToEnum(type);

	}

	private FieldType convertTypeToEnum(String type) {
		switch (type) {
			case "TEXT_FIELD":
				return FieldType.TEXT_FIELD;
			case "TEXT_AREA":
				return FieldType.TEXT_AREA;
			case "DROPDOWN":
				return FieldType.DROPDOWN;
			case "CHECK_BOX_GROUP":
				return FieldType.CHECK_BOX_GROUP;
			case "SELECT_MANY":
				return FieldType.SELECT_MANY;
			case "RADIO_BUTTON_GROUP":
				return FieldType.RADIO_BUTTON_GROUP;
			case "DATE_PICKER":
				return FieldType.DATE_PICKER;
			case "DATE_TIME_PICKER":
				return FieldType.DATE_TIME_PICKER;
			case "TIME_PICKER":
				return FieldType.TIME_PICKER;
			case "BAR_CODE":
				return FieldType.BARCODE_SCANNER;
			case "SINGLE_ATTACHMENT":
				return FieldType.SINGLE_ATTACHMENT;
			default:
				FLLogger.d(TAG, "Unsupported field: " + type);
				return FieldType.UNSUPPORTED;
		}
	}

	// ========================================================================
	// Exceptions

	public static class InvalidFormFieldException extends Exception {

		private static final long serialVersionUID = 668103959494161980L;

		public InvalidFormFieldException(String message) {
			super(message);
		}

		public InvalidFormFieldException(String message, Throwable throwable) {
			super(message, throwable);
		}

	}

}
